package com.cloud.controller.uploadfile;

import com.cloud.commons.utils.DateUtils;
import com.cloud.commons.utils.message.MessageCode;
import com.cloud.commons.utils.message.MessageDescription;
import com.cloud.commons.utils.message.Result;
import com.cloud.commons.utils.message.ResultUtil;
import io.swagger.annotations.*;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;


@RestController
@RequestMapping(value = "/api")
@Api(value = "[Cloud Source]上传图片接口", tags = "[Cloud Source]上传图片接口", description = "")
public class UploadController {

    private static final Logger LOG = LoggerFactory.getLogger(UploadController.class);

    //图片存放根路径
    @Value("${file.rootPath}")
    private String ROOT_PATH;
    //图片存放根路径
    @Value("${file.sonPath}")
    private String SON_PATH;

    @ApiOperation(value = "[Cloud Source]上传记账图片接口", notes = "[Cloud Source]上传记账图片接口")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "successful request"),
            @ApiResponse(code = 500, message = "internal server error")})
    @RequestMapping(value = "/v1/upload/{filePath}", method = RequestMethod.POST)
    @ResponseBody
    public Result<?> userUpload(@ApiParam(value = "filePath", required = true) @PathVariable("filePath") String filePath,
                                     @ApiParam(value = "file", required = true) @RequestParam("file") MultipartFile file) {
        try {
            String path = this.getUploadFilePath(file,filePath);

            return ResultUtil.success(MessageCode.SUCCESS_CODE_200, MessageDescription.OPERATION_INSERT_SUCCESS,path);
        }catch (Exception e){
            return ResultUtil.error(MessageCode.ERROR_CODE_500,e.getMessage());
        }

    }

    @ApiOperation(value = "[Cloud Source]上传记账记录图", notes = "[Cloud Source]上传记账记录图")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "successful request"),
            @ApiResponse(code = 500, message = "internal server error")})
    @RequestMapping(value = "/v1/upload/bookkeeping/{filePath}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = {RequestMethod.POST})
    public Result<?> uploadProductCommentImage(@ApiParam(value = "filePath", required = true) @PathVariable("filePath") String filePath,
                                                    HttpServletRequest request, HttpServletResponse response) {
        try {
            String path = upload(request, filePath);
            return ResultUtil.success(MessageCode.SUCCESS_CODE_200,MessageDescription.OPERATION_INSERT_SUCCESS,path);
        }catch (Exception e){
            return ResultUtil.error(MessageCode.ERROR_CODE_500,e.getMessage());
        }
    }

    public String getUploadFilePath(MultipartFile file,String filePathRequest){
        //返回上传的文件是否为空，即没有选择任何文件，或者所选文件没有内容。
        //防止上传空文件导致奔溃
        if (file.isEmpty()) {
            throw new NullPointerException("文件为空");
        }
        // 设置文件上传后的路径
        String filePath = ROOT_PATH +  SON_PATH + filePathRequest + "/";
        // 获取文件名后缀名
        String suffix = file.getOriginalFilename();
        String prefix = suffix.substring(suffix.lastIndexOf(".")+1);
        //为防止文件重名被覆盖，文件名取名为：当前日期 + 1-1000内随机数
        Random random = new Random();
        Integer randomFileName = random.nextInt(1000);
        String fileName = DateUtils.timeStamp2Date(String.valueOf(System.currentTimeMillis() /100),"yyyyMMddHHmmss") + randomFileName +"." +  prefix;
        //创建文件路径
        System.out.println("file:" + filePath + fileName);

        File dest = new File(filePath + fileName);
        // 解决中文问题，liunx下中文路径，图片显示问题
        // fileName = UUID.randomUUID() + suffixName;
        // 检测是否存在目录
        if (!dest.getParentFile().exists()) {
            //假如文件不存在即重新创建新的文件已防止异常发生
            dest.getParentFile().mkdirs();
        }
        try {
            //transferTo（dest）方法将上传文件写到服务器上指定的文件
            file.transferTo(dest);
            String filePathNew = SON_PATH + filePathRequest + "/" +  fileName;
            return filePathNew;
        } catch (Exception e) {
            return dest.toString();
        }
    }

    /**
     * 具体保存操作
     *
     * @param request
     * @param type
     * @return
     */
    private String upload(HttpServletRequest request, String type) {
        MultipartHttpServletRequest mhs = (MultipartHttpServletRequest) request;
        MultipartFile file = mhs.getFile("file");
        ServletContext application = request.getSession().getServletContext();
        LOG.info("pic url: " + application.getRealPath("/"));
        String savePath = ROOT_PATH + SON_PATH;
        String filePath = type + "/";
        String newFileName = "";
        try {
            if (file != null && !file.isEmpty()) {

                //检查是否有文件夹
                String folderName = savePath  + type;
                File folder = new File(folderName);
                //没有则创建
                if (!folder.exists() && !folder.isDirectory()) {
                    LOG.info("创建文件夹：" + folderName);
                    folder.mkdir();
                }

                SimpleDateFormat bartDateFormat = new SimpleDateFormat
                        ("yyyyMMddHHmmss");
                newFileName = String.valueOf(bartDateFormat.format(new Date()));
                filePath = filePath + newFileName + "_" + Math.round(Math.random()*1000);
                LOG.info("上传文件： " + filePath);
                FileUtils.writeByteArrayToFile(new File(savePath + filePath), file.getBytes());

            }
        } catch (Exception e) {
            LOG.error("Fail to upload file ",e);
        }
        return SON_PATH + filePath;

    }
}
